<?php defined('SYSPATH') or die('No direct script access.');

/**
 * Twitter Service Driver Library
 * http://apiwiki.twitter.com/REST+API+Documentation
 *
 * $Id: Twitter.php 158 2008-10-27 16:05:20Z alex.aperez $
 *
 * @package		Service Module
 * @author		Alex Sancho
 * @copyright	(c) 2008 Alex Sancho
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 * 3. Neither the name of copyright holders nor the names of its
 *	  contributors may be used to endorse or promote products derived
 *	  from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

class Service_Twitter_Driver extends Service_Driver 
{
	protected $api_url = "twitter.com";
	protected $format = 'xml';

	/**
	 *	__construct
	 * 
	 * @param array $config
	 * @return void
	 * @access public
	 * 
	 */
	public function __construct($config = array()) 
	{
		$config += Kohana::config('service.twitter');

		foreach($config as $key => $val)
			$this->$key = $val;
	}

	/**
	 * get_public_timeline
	 *
	 * @param integer $since_id
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_public_timeline($since_id = 0) 
	{
		$api_url = '/statuses/public_timeline.'.$this->format;

		if ($since_id > 0) 
			$api_url .= '?'.http_build_query(array($since_id));

		return $this->api_call($api_url);
	}
	
	/**
	 * get_friends_timeline
	 *
	 * @param integer $id
	 * @param integer $since
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_friends_timeline($id = null, $since = null) 
	{
		if ($id !== null) 
		{
			$api_url = '/statuses/friends_timeline/'.$id.'.'.$this->format;
		}
		else 
		{
			$api_url = '/statuses/friends_timeline.'.$this->format;
		}

		if ($since !== null) 
		{
			$api_url .= '?'.http_build_query(array('since' => $since));
		}

		return $this->api_call($api_url, true);
	}

	/**
	 * get_user_timeline
	 *
	 * @param integer $id
	 * @param integer $count
	 * @param integer $since
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_user_timeline($id = null, $count = 20, $since = null) 
	{
		$query = array();

		if ($id !== null) 
		{
			$api_url = '/statuses/user_timeline/'.$id.'.'.$this->format;
		}
		else 
		{
			$api_url = '/statuses/user_timeline.'.$this->format;
		}
	
		if ($count != 20) 
			$query['count'] = $count;
	
		if ($since != null) 
			$query['since'] = $since;
		
		if (count($query) > 0)
		    $api_url .= '?'.http_build_query($query);

		return $this->api_call($api_url, true);
	}

	/**
	 * show_status
	 *
	 * @param integer $id
	 * @return mixed
	 * @access public
	 *
	 */
	public function show_status($id) 
	{
		return $this->api_call('/statuses/show/'.$id.'.'.$this->format);
	}

	/**
	 * update_status
	 *
	 * @param string $status
	 * @return mixed
	 * @access public
	 *
	 */
	public function update_status($status) 
	{
		return $this
				->post()
				->api_call('/statuses/update.'.$this->format.'?'.http_build_query(array('status' => $status)), true);
	}
	
	/**
	 * get_replies
	 *
	 * @param integer $page
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_replies($page = 0) 
	{
		$api_url = '/statuses/replies.'.$this->format;

		if ($page > 0) 
			$api_url .= '?'.http_build_query(array('page' => $page));

		return $this->api_call($api_url, true);
	}

	/**
	 * destroy_status
	 *
	 * @param integer $id
	 * @return mixed
	 * @access public
	 *
	 */
	public function destroy_status($id) 
	{
		return $this->api_call('/statuses/destroy/'.$id.'.'.$this->format, true);
	}

	/**
	 * get_friends
	 *
	 * @param integer $id
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_friends($id = null) 
	{
		if ($id !== null) 
		{
			$api_url = '/statuses/friends/'.$id.'.'.$this->format;
		}
		else 
		{
			$api_url = '/statuses/friends.'.$this->format;
		}

		return $this->api_call($api_url, true);
	}

	/**
	 * get_followers
	 *
	 * @param boolean $lite
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_followers($lite = null) 
	{
	    return $this->api_call(sprintf("/statuses/followers.%s%s", $this->format, ($lite) ? "?lite=true" : null), true);
	}

	/**
	 * get_featured
	 *
	 * @return mixed
	 * @access public
	 *
	 */
	public function get_featured() 
	{
		return $this->api_call('/statuses/featured.'.$this->format);
	}

	/**
	 * show_user
	 *
	 * @param mixed $id
	 * @return mixed
	 * @access public
	 *
	 */
	public function show_user($id) 
	{
		if (valid::email($id)) 
		{
		    $api_url = '/users/show.xml?email='.$id;
		}
		else 
		{
		    $api_url = '/users/show/'.$id.'.'.$this->format;
		}
	
		return $this->api_call($api_url, true);
	}

	/**
	 * get_messages
	 * 
	 * @param integer $since
	 * @param integer $since_id
	 * @param integer $page
	 * @return mixed
	 * @access public
	 * 
	 */
	public function get_messages($since = null, $since_id = 0, $page = 1) 
	{
		$query = array();

		$api_url = '/direct_messages.'.$this->format;

		if ($since !== null) 
			$query['since'] = $since;
	
		if ($since_id > 0) 
			$query['since_id'] = $since_id;
	
		if ($page > 1) 
			$query['page'] = $page;
		
		if (count($query) > 0)
		    $api_url .= '?'.http_build_query($query);

		return $this->api_call($api_url, true);
	}

	/**
	 * get_sent_messages
	 * 
	 * @param integer $since
	 * @param integer $since_id
	 * @param integer $page
	 * @return mixed
	 * @access public
	 * 
	 */
	public function get_sent_messages($since = null, $since_id = 0, $page = 1) 
	{
		$query = array();
		
		$api_url = '/direct_messages/sent.'.$this->format;
	
		if ($since !== null) 
			$query['since'] = $since;
	
		if ($since_id > 0) 
			$query['since_id'] = $since_id;
	
		if ($page > 1) 
			$query['page'] = $page;
		
		if (count($query) > 0)
		    $api_url .= '?'.http_build_query($query);
	
		return $this->api_call($api_url, true);
	}

	/**
	 * new_message
	 * 
	 * @param string $user
	 * @param string $text
	 * @return mixed
	 * @access public
	 * 
	 */
	public function new_message($user, $text) 
	{
		$query = array
		(
		    'user' => $user,
		    'text' => $text
		);

		return $this
				->post()
				->api_call('/direct_messages/new.'.$this->format.'?'.http_build_query($query), true);
	}

	/**
	 * destroy_message
	 * 
	 * @param integer $id
	 * @return mixed
	 * @access public
	 * 
	 */
	public function destroy_message($id) 
	{
		return $this->api_call('/direct_messages/destroy/'.$id.'.'.$this->format, true);
	}

	/**
	 * create_friendship
	 * 
	 * @param mixed $id
	 * @return mixed
	 * @access public
	 * 
	 */
	public function create_friendship($id) 
	{
		return $this->api_call('/friendships/create/'.$this->format.'.'.$id, true);
	}

	/**
	 * destroy_friendship
	 * 
	 * @param mixed $id
	 * @return mixed
	 * @access public
	 * 
	 */
	public function destroy_friendship($id) 
	{
		return $this->api_call('/friendships/destroy/'.$this->format.'.'.$id, true);
	}
	
	/**
	 * verify_credentials
	 * 
	 * @return mixed
	 * @access public
	 * 
	 */
	public function verify_credentials() 
	{
		return $this->api_call('/account/verify_credentials.'.$this->format, true);
	}

	/**
	 * end_session
	 * 
	 * @return mixed
	 * @access public
	 * 
	 */
	public function end_session() 
	{
		return $this->api_call('/account/end_session', true);
	}

	/**
	 * get_archive
	 * 
	 * @param integer $page
	 * @return mixed
	 * @access public
	 * 
	 */
	public function get_archive($page = 1) 
	{
		$api_url = '/account/archive.'.$this->format;

		if ($page > 1) 
			$api_url .= '?'.http_build_query(array('page' => $page));
	
		return $this->api_call($api_url, true);
	}

	/**
	 * get_favorites
	 * 
	 * @param mixed $id
	 * @param integer $page
	 * @return mixed
	 * @access public
	 * 
	 */
	public function get_favorites($id = null, $page = 1) 
	{
		if ($id === null) 
		{
			$api_url = '/favourings.'.$this->format;
		}
		else 
		{
			$api_url = '/favourings/'.$id.'.'.$this->format;
		}
	
		if ($page > 1) 
			$api_url .= '?'.http_build_query(array('page' => $page));

		return $this->api_call($api_url, true);
	}

	/**
	 * create_favorite
	 * 
	 * @param integer $id
	 * @return mixed
	 * @access public
	 * 
	 */
	public function create_favorite($id) 
	{
		return $this->api_call('/favourings/create/'.$id.'.'.$this->format, true);
	}

	/**
	 * destroy_favorite
	 * 
	 * @param mixed $id
	 * @return mixed
	 * @access public
	 * 
	 */
	public function destroy_favorite($id) 
	{
		return $this->api_call('/favourings/destroy/'.$id.'.'.$this->format, true);
	}

	/**
	 * api_call
	 * 
	 * @param string $api_url
	 * @param boolean $credentials
	 * @return mixed
	 * @access protected
	 * 
	 */
	protected function api_call($api_url, $credentials = false) 
	{
		if ( ! $result = parent::api_call($api_url, $credentials))
			throw new Kohana_User_Exception('Twitter Driver', Kohana::lang('service.invalid_response', $this->last_api_call(), $this->last_status_code()));
	
		if ($this->format == 'xml')
		{
			$result = simplexml_load_string($result);

			if (false === $result)
				throw new Kohana_User_Exception('Twitter Driver', Kohana::lang('service.xml_parse_error'));
		}

		return $result;
	}

} //End Twitter Driver